package com.sec.etech.ism.util;

import com.alibaba.fastjson.JSONObject;
import com.sec.etech.ism.constant.SignatureConstant;
import org.openbpm.base.core.util.StringUtil;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class EtechSignatureUtil {

    /**
     * 构建接口请求体的内容
     * @param appSecrete 签名秘钥（分配的系统秘钥）
     * @param timeStamp 时间戳
     * @return 返回调用接口的请求体内容
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws UnsupportedEncodingException
     */
    public static JSONObject buildRequestParamsByTimeStamp(JSONObject inputParams, String appSecrete, Long timeStamp)
            throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
        return SignatureUtil.buildRequestParamsByTimeStamp(inputParams, appSecrete, timeStamp, SignatureConstant.SIGNATURE_MAC);
    }

    /**
     * 构建接口请求体的内容，使用系统当前时间作为时间戳进行构建
     * @param inputParams 参数内容
     * @param appSecrete 签名秘钥（分配的系统秘钥）
     * @return 返回调用接口的请求体内容
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws UnsupportedEncodingException
     */
    public static JSONObject buildRequestParams(JSONObject inputParams, String appSecrete) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
        return buildRequestParamsByTimeStamp(inputParams, appSecrete, System.currentTimeMillis() / 1000);
    }
    /**
     * 只检查签名是否一致，返回布尔值
     * @param requestParams 带签名的请求参数
     * @param appSecrete 秘钥
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws UnsupportedEncodingException
     */
    public static boolean checkSignature(JSONObject requestParams, String appSecrete)
            throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
        return SignatureUtil.checkSignature(requestParams, appSecrete, SignatureConstant.SIGNATURE_MAC);
    }
    /**
     * 检查参数、签名是否一致、是否失效，返回字符串
     * @param requestParams 带签名的请求参数
     * @param appSecrete 秘钥
     * @param validTime 有效时间（分钟）
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws UnsupportedEncodingException
     */
    public static String checkSignature(JSONObject requestParams, String appSecrete, int validTime)
            throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
        if(StringUtil.isEmpty(requestParams.getString(SignatureConstant.SIGNATURE_CREATED))
                || StringUtil.isEmpty(requestParams.getString(SignatureConstant.SIGNATURE_PARAMS))
                || StringUtil.isEmpty(requestParams.getString(SignatureConstant.INPUT_PARAMS))){
            return "请检查签名和相关参数！";
        }else if(!checkSignature(requestParams, appSecrete)){
            return "签名校验不一致！";
        }else if(System.currentTimeMillis() / 1000 - requestParams.getInteger(SignatureConstant.SIGNATURE_CREATED).intValue() > validTime*60){
            return "签名已失效！";
        }
        return null;
    }
    /**
     * 时间戳:1658910346
     * 1、需要签名的字符串:{"material_no":"GD61018100040"}
     * 1658910346
     * 2、参数签名结果:KwhN76eZG42NsbAJshv6/4gyEr/z8ijfblJbpI3P8gU=
     * 3、请求参数格式如下:{"signature_created":1658910346,"signature":"KwhN76eZG42NsbAJshv6/4gyEr/z8ijfblJbpI3P8gU=","input_params":{"material_no":"GD61018100040"}}
     * @param appSecret
     * @throws Exception
     */
    public static void  test(String appSecret) throws Exception{
        //参数内容JSON
        JSONObject inputParams = new JSONObject();
        inputParams.put("material_no", "GD61018100040");

        buildRequestParamsByTimeStamp(inputParams, appSecret,1658910346L);
    }

    /**
     * 主函数
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        try {
            //System.out.println(UUID.randomUUID());
            //秘钥
            String appSecret = "64392c5a-2fa1-4cde-aeb2-5304b3258d95";

            //System.out.printf("\n\n测试验证签名方法是否符合预期：\n\n");
            //test(appSecret);

            //参数内容JSON
            JSONObject inputParams = new JSONObject();
            inputParams.put("projectid", "10086");

            System.out.printf("\n\n使用当前时间作为时间戳，构建请求体的内容：\n\n");
            JSONObject ss = buildRequestParams(inputParams,appSecret);
            System.out.println(ss);


        } catch (Exception e) {
            System.out.println("Error");
            e.printStackTrace();
        }
    }
}
